package gui;

public class MainWindow extends javax.swing.JFrame implements core.interfaces.CoreCallbackInterface, gui.callback.PadCallbackInterface, core.interfaces.InterruptInterface{
	private static final long serialVersionUID = 1L;

	private static final java.lang.String version = "2.1.2";

	private javax.swing.JToolBar jtoolbar = null;
	private javax.swing.JPanel botoneralateral = null;
	private javax.swing.JMenuBar jmenu = null;
	private gui.MainWindow mainWindow = this;
	private javax.swing.JTextField PCField = null;
	private javax.swing.JTextField NField = null;
	private javax.swing.JTextField ZField = null;
	private javax.swing.JTextField CField = null;
	private javax.swing.JTextField VField = null;
	private javax.swing.JTextField EIField = null;
	private javax.swing.JTextField TField = null;
	private javax.swing.JTextField HField = null;
	private javax.swing.JTextField LField = null;
	//private javax.swing.JTextField SField = null;
	private javax.swing.JTextField TMField = null;
	private javax.swing.JTextField HMField = null;
	private javax.swing.JTextField LMField = null;
	//private javax.swing.JTextField SMField = null;

	private core.interfaces.DeviceInterface timer = null;

	private devices.NetDevice netDevice = null;
	private javax.swing.JCheckBoxMenuItem netMenuItem = new javax.swing.JCheckBoxMenuItem();

	private boolean silentRun = false;
	private devices.PadWindow pad = null;
	private boolean padVisible = false;
	private javax.swing.JCheckBoxMenuItem padMenuItem = new javax.swing.JCheckBoxMenuItem();

	private javax.swing.JCheckBoxMenuItem followPCMenuItem = new javax.swing.JCheckBoxMenuItem();
	private javax.swing.JCheckBoxMenuItem colourMemoryChanges = new javax.swing.JCheckBoxMenuItem();
	private javax.swing.JCheckBoxMenuItem colourMemoryAccess = new javax.swing.JCheckBoxMenuItem();
	private javax.swing.JCheckBoxMenuItem colourRegisterChanges = new javax.swing.JCheckBoxMenuItem();
	private javax.swing.JCheckBoxMenuItem colourRegisterAccess = new javax.swing.JCheckBoxMenuItem();

	private java.awt.Font registerFont = new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.PLAIN, 17);
	private java.awt.Font valuesFont = new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.PLAIN, 12);
	public core.ProcessorClass processor = null;

	private java.io.File fileChooserDirectory = null;
	private boolean programModified = false;

	public MainWindow(core.ProcessorClass p){
		super();
		init(p, null, null, null);
	}
	public MainWindow(core.ProcessorClass p, devices.PadWindow pad, core.interfaces.DeviceInterface timer, devices.NetDevice net){
		super();
		init(p, pad, timer, net);
	}
	private void call_exit(){
		if(this.netDevice != null){
			if(this.netDevice.isRunning()){
				this.netDevice.sstop();
			}
		}
		System.exit(0);
	}
	protected void prepare_exit(){
		//Operations to prepare exit of the program
		if(this.programModified){
			java.lang.Object[] opts = {"Save", "Discard", "Don't close"};
			int res = javax.swing.JOptionPane.showOptionDialog(mainWindow, "The program has changed.\nWould you like to save it to a file?", "Close", javax.swing.JOptionPane.YES_NO_CANCEL_OPTION, javax.swing.JOptionPane.WARNING_MESSAGE, null, opts, null);
			switch(res){
			case 0:
				this.doSaveFile();
				if(this.programModified){
					return;
				}else{
					this.call_exit();
				}
				break;
			case 1:
				this.call_exit();
				break;
			case 2:
			default:
				return;
			}
		}else{
			this.call_exit();
		}
	}
	protected void informaCanviTamany(){
		if(this.pad != null){
			this.pad.setLocation(this.getLocation().x + this.getWidth(), this.getLocation().y);
		}
	}
	public void setPad(devices.PadWindow pad){
		this.pad = pad;
		this.padVisible = true;
		this.informaCanviTamany();
	}
	public void setTimer(core.interfaces.DeviceInterface timer){
		this.timer = timer;
	}
	public void setNetDevice(devices.NetDevice net){
		this.netDevice = net;
	}
	private void init(core.ProcessorClass p, devices.PadWindow pad, core.interfaces.DeviceInterface timer, devices.NetDevice netDevice){
		this.processor = p;
		this.pad = pad;
		this.timer = timer;
		this.netDevice = netDevice;
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent e) {
				prepare_exit();
			}
		});
		this.addComponentListener(new java.awt.event.ComponentAdapter() {
			public void componentResized(java.awt.event.ComponentEvent e) {
				informaCanviTamany();
			}
			public void componentMoved(java.awt.event.ComponentEvent e) {
				informaCanviTamany();
			}
		});
		this.initFonts();
		this.setTitle("SEP16 Simulator");
//		this.setContentPane(this.getContentPanel());
		this.setJMenuBar(this.initMenuBar());
		this.getContentPane().setLayout(new java.awt.BorderLayout());
		this.getContentPane().add(this.initToolBar(), java.awt.BorderLayout.NORTH);
		this.getContentPane().add(this.getPanellGeneral(), java.awt.BorderLayout.CENTER);
		this.setSize(new java.awt.Dimension(850,650));
//		this.pack();
		this.setVisible(true);
		this.informaCanviTamany();
	}

	private void initFonts(){
		java.lang.String fName = "/util/consolas.ttf";
		java.awt.Font auxFont = null;
		try {
			java.io.InputStream is = MainWindow.class.getResourceAsStream(fName);
			auxFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, is);
		} catch (Exception ex) {
			System.err.println(fName + " not loaded.  Using default Monospaced font.");
			auxFont = new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.PLAIN, 1);
		}
		this.registerFont = auxFont.deriveFont((float)17);
		this.valuesFont = auxFont.deriveFont((float)14);
	}

	private javax.swing.JPanel getPanellGeneral(){
		javax.swing.JPanel aux = new javax.swing.JPanel(new java.awt.GridBagLayout());
		java.awt.GridBagConstraints c;
		c = new java.awt.GridBagConstraints(0, 0, 1, 2, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(10,10,10,10), 0, 0);
		aux.add(this.getProgramPanel(), c);
		c = new java.awt.GridBagConstraints(2, 0, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.NORTH, java.awt.GridBagConstraints.HORIZONTAL, new java.awt.Insets(10,0,10,10), 0, 0);
		aux.add(this.getRegisterPanel(), c);
		c = new java.awt.GridBagConstraints(3, 0, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.NORTH, java.awt.GridBagConstraints.HORIZONTAL, new java.awt.Insets(10,0,10,10), 0, 0);
		aux.add(this.getStackPanel(), c);
		c = new java.awt.GridBagConstraints(1, 0, 1, 2, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(10,0,10,10), 0, 0);
		aux.add(this.getMemoryPanel(), c);
		c = new java.awt.GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, java.awt.GridBagConstraints.NORTH, java.awt.GridBagConstraints.VERTICAL, new java.awt.Insets(20,0,10,10), 0, 0);
		aux.add(this.getBotoneraLateral(), c);
		c = new java.awt.GridBagConstraints(2, 1, 3, 1, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(0,0,10,10), 0, 0);
		aux.add(this.getBotomPanel(), c);
		return(aux);
	}

	//The ToolBar (not initializated yet)
	private javax.swing.JToolBar initToolBar(){
		this.jtoolbar = new javax.swing.JToolBar();
		return(this.jtoolbar);
	}
	private void doLoadFile(){
		javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
		javax.swing.filechooser.FileNameExtensionFilter filter = new javax.swing.filechooser.FileNameExtensionFilter("SEP16 Simulator program files (*.s16)", "s16");
		jfc.setFileFilter(filter);
		jfc.setCurrentDirectory(this.fileChooserDirectory);
		int retval = jfc.showOpenDialog(mainWindow);
		if(retval == javax.swing.JFileChooser.APPROVE_OPTION){
			//System.out.println("Chosen file: " + jfc.getSelectedFile().getName());
			processor.progReset();
			processor.loadFile(jfc.getSelectedFile());
			mainWindow.registerChanges.clear();
			mainWindow.memoryChanges.clear();
			mainWindow.registerAccess.clear();
			mainWindow.memoryAccess.clear();
			this.fileChooserDirectory = new java.io.File(jfc.getSelectedFile().getParent());
			this.programModified = false;
		}else{
			//System.out.println("Not choosen file");
		}
	}
	private void doSaveFile(){
		javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
		javax.swing.filechooser.FileNameExtensionFilter filter = new javax.swing.filechooser.FileNameExtensionFilter("SEP16 Simulator program files (*.s16)", "s16");
		jfc.setFileFilter(filter);
		jfc.setCurrentDirectory(this.fileChooserDirectory);
		boolean fileDone = false;
		while(!fileDone){
			fileDone = true;
			int retval = jfc.showSaveDialog(mainWindow);
			if(retval == javax.swing.JFileChooser.APPROVE_OPTION){
				java.io.File f = jfc.getSelectedFile();
				this.fileChooserDirectory = new java.io.File(jfc.getSelectedFile().getParent());
				//Add suffix .s16 if not provided:
				if(!f.getName().endsWith(".s16")){
					f = new java.io.File(f.getAbsolutePath() + ".s16");
				}
				if(f.exists()){
					//Ask if we are sure to overwrite that file
					int res = javax.swing.JOptionPane.showConfirmDialog(mainWindow, "The file exists.\nOverwrite that file?", "Confirmate Overwrite", javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.ERROR_MESSAGE);
					if(res == 0){
						processor.saveFile(f);
						this.programModified = false;
					}else{
						//Reopen the JFileChooser
						fileDone = false;
					}
				}else{
					processor.saveFile(f);
					this.programModified = false;
				}
			}else{
				//System.out.println("Not choosen file");
			}
		}
	}

	//Lateral Command Buttons
	private javax.swing.JPanel getBotoneraLateral(){
		//this.botoneralateral = new javax.swing.JPanel(new java.awt.GridLayout(0,1));
		this.botoneralateral = new javax.swing.JPanel();
		javax.swing.BoxLayout l = new javax.swing.BoxLayout(this.botoneralateral, javax.swing.BoxLayout.Y_AXIS);
		this.botoneralateral.setLayout(l);
		//this.botoneralateral.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 10, 10, 10));
		//Reset:
		javax.swing.JButton auxBoto = new javax.swing.JButton();
		auxBoto.setText("H RESET");
		auxBoto.setPreferredSize(new java.awt.Dimension(90,30));
		auxBoto.setMinimumSize(new java.awt.Dimension(90,30));
		auxBoto.setMaximumSize(new java.awt.Dimension(90,30));
		auxBoto.setAlignmentX(javax.swing.JButton.CENTER_ALIGNMENT);
		auxBoto.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				processor.hardReset();
				mainWindow.registerChanges.clear();
				mainWindow.memoryChanges.clear();
				mainWindow.registerAccess.clear();
				mainWindow.memoryAccess.clear();

			}
		});
		this.botoneralateral.add(auxBoto);
		
		this.botoneralateral.add(javax.swing.Box.createRigidArea(new java.awt.Dimension(0, 20)));

		auxBoto = new javax.swing.JButton();
		auxBoto.setText("RESET");
		auxBoto.setPreferredSize(new java.awt.Dimension(90,30));
		auxBoto.setMinimumSize(new java.awt.Dimension(90,30));
		auxBoto.setMaximumSize(new java.awt.Dimension(90,30));
		auxBoto.setAlignmentX(javax.swing.JButton.CENTER_ALIGNMENT);
		auxBoto.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				processor.reset();
				mainWindow.registerChanges.clear();
				mainWindow.memoryChanges.clear();
				mainWindow.registerAccess.clear();
				mainWindow.memoryAccess.clear();
			}
		});
		this.botoneralateral.add(auxBoto);
		this.botoneralateral.add(javax.swing.Box.createRigidArea(new java.awt.Dimension(0, 20)));

		//Exec
		auxBoto = new javax.swing.JButton();
		auxBoto.setText("RUN");
		auxBoto.setPreferredSize(new java.awt.Dimension(90,30));
		auxBoto.setMinimumSize(new java.awt.Dimension(90,30));
		auxBoto.setMaximumSize(new java.awt.Dimension(90,30));
		auxBoto.setAlignmentX(javax.swing.JButton.CENTER_ALIGNMENT);
		auxBoto.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				//Exec loaded program
				mainWindow.silentRun = false;
				processor.start();
			}
		});
		this.botoneralateral.add(auxBoto);
		this.botoneralateral.add(javax.swing.Box.createRigidArea(new java.awt.Dimension(0, 20)));

		//Silent Exec
		auxBoto = new javax.swing.JButton();
		auxBoto.setText("S-RUN");
		auxBoto.setPreferredSize(new java.awt.Dimension(90,30));
		auxBoto.setMinimumSize(new java.awt.Dimension(90,30));
		auxBoto.setMaximumSize(new java.awt.Dimension(90,30));
		auxBoto.setAlignmentX(javax.swing.JButton.CENTER_ALIGNMENT);
		auxBoto.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				//Exec loaded program
				mainWindow.silentRun = true;
				processor.start();
			}
		});
		this.botoneralateral.add(auxBoto);
		this.botoneralateral.add(javax.swing.Box.createRigidArea(new java.awt.Dimension(0, 20)));

		//Stop
		auxBoto = new javax.swing.JButton();
		auxBoto.setText("STOP");
		auxBoto.setPreferredSize(new java.awt.Dimension(90,30));
		auxBoto.setMinimumSize(new java.awt.Dimension(90,30));
		auxBoto.setMaximumSize(new java.awt.Dimension(90,30));
		auxBoto.setAlignmentX(javax.swing.JButton.CENTER_ALIGNMENT);
		auxBoto.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				processor.stop();
			}
		});
		this.botoneralateral.add(auxBoto);
		this.botoneralateral.add(javax.swing.Box.createRigidArea(new java.awt.Dimension(0, 20)));

		//Step:
		auxBoto = new javax.swing.JButton();
		auxBoto.setText("STEP");
		auxBoto.setPreferredSize(new java.awt.Dimension(90,30));
		auxBoto.setMinimumSize(new java.awt.Dimension(90,30));
		auxBoto.setMaximumSize(new java.awt.Dimension(90,30));
		auxBoto.setAlignmentX(javax.swing.JButton.CENTER_ALIGNMENT);
		auxBoto.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				mainWindow.registerChanges.clear();
				mainWindow.memoryChanges.clear();
				mainWindow.registerAccess.clear();
				mainWindow.memoryAccess.clear();
				processor.step();
			}
		});
		this.botoneralateral.add(auxBoto);

		return(this.botoneralateral);
	}

	//The General Menu Bar
	private javax.swing.JMenuBar initMenuBar(){
		this.jmenu = new javax.swing.JMenuBar();
		this.jmenu.add(this.initFileMenu());
		this.jmenu.add(this.initViewMenu());
		this.jmenu.add(this.initConfMenu());
		this.jmenu.add(this.initHelpMenu());
		return(this.jmenu);
	}
	private javax.swing.JMenu initFileMenu(){
		javax.swing.JMenu filemenu = new javax.swing.JMenu();
		filemenu.setText("File");

		javax.swing.JMenuItem item = new javax.swing.JMenuItem("Load File");
		item.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				doLoadFile();
			}
		});
		filemenu.add(item);
		
		item = new javax.swing.JMenuItem("Save to File");
		item.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				doSaveFile();
			}
		});
		filemenu.add(item);
		
		item = new javax.swing.JMenuItem("Exit");
		item.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				prepare_exit();
			}
		});
		filemenu.add(item);
		return(filemenu);
	}
	private javax.swing.JMenu initHelpMenu(){
		javax.swing.JMenu filemenu = new javax.swing.JMenu();
		filemenu.setText("Help");
		javax.swing.JMenuItem item = new javax.swing.JMenuItem();
		item.setText("About");
		item.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				//Show a dialog
				javax.swing.JOptionPane.showMessageDialog(null, "SEP16 Simulator v." + gui.MainWindow.version + "\nCreated by Ximo Tur <ximotur at gmail dot com>\nUniversitat Politècnica de València");
			}
		});
		filemenu.add(item);
		return(filemenu);
	}
	private javax.swing.JMenu initConfMenu(){
		javax.swing.JMenu confMenu = new javax.swing.JMenu();
		confMenu.setText("Configuration");

		this.followPCMenuItem.setSelected(true);
		this.followPCMenuItem.setText("Program panel follows PC");
		confMenu.add(this.followPCMenuItem);

		confMenu.addSeparator();
		javax.swing.JMenuItem mi;
		
		mi = new javax.swing.JMenuItem("Processor Frequency");
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				boolean done = false;
				while(!done){
					java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, "New processor frequency (Hz):", "Processor Frequency", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("%d", mainWindow.processor.getFreq()));
					if(s==null){
						done = true;
					}else{
						try{
							java.lang.Integer newFreq = java.lang.Integer.decode(s);
							mainWindow.processor.setFreq(newFreq.intValue());
							done = true;
						}catch(java.lang.NumberFormatException ex){
							mainWindow.error("Please enter a positive integer value");
						}
					}
				}
			}
		});
		confMenu.add(mi);
		confMenu.addSeparator();

		confMenu.add(this.initNetDeviceMenu());

		mi = new javax.swing.JMenuItem("SP Base Address");
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				boolean done = false;
				while(!done){
					java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, "New base address for SP", "SP Base Address", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("0x%04X", mainWindow.processor.getBaseSP()));
					if(s == null){
						done = true;
					}else{
						try{
							java.lang.Integer newAddress = java.lang.Integer.decode(s);
							mainWindow.processor.setBaseSP(newAddress.intValue());
							done = true;
						}catch(java.lang.NumberFormatException ex){
							mainWindow.error("Please enter a positive integer value");
						}
					}
				}
			}
		});
		confMenu.add(mi);

		mi = new javax.swing.JMenuItem("PAD Base Address");
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				boolean done = false;
				if(mainWindow.pad != null){
					while(!done){
						java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, "New base address for PAD", "PAD Base Address", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("0x%04X", mainWindow.pad.getBaseAddress()));
						if(s == null){
							done = true;
						}else{
							try{
								java.lang.Integer newAddress = java.lang.Integer.decode(s);
								mainWindow.pad.setBaseAddress(newAddress.intValue());
								done = true;
							}catch(java.lang.NumberFormatException ex){
								mainWindow.error("Please enter a positive integer value");
							}
						}
					}
				}
			}
		});
		confMenu.add(mi);

		mi = new javax.swing.JMenuItem("Timer Base Address");
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				boolean done = false;
				if(mainWindow.timer != null){
					while(!done){
						java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, "New base address for Timer", "Timer Base Address", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("0x%04X", mainWindow.timer.getBaseAddress()));
						if(s == null){
							done = true;
						}else{
							try{
								java.lang.Integer newAddress = java.lang.Integer.decode(s);
								mainWindow.timer.setBaseAddress(newAddress.intValue());
								done = true;
							}catch(java.lang.NumberFormatException ex){
								mainWindow.error("Please enter a positive integer value");
							}
						}
					}
				}
			}
		});
		confMenu.add(mi);

		return(confMenu);
	}
	private javax.swing.JMenu initNetDeviceMenu(){
		javax.swing.JMenu netMenu = new javax.swing.JMenu();
		netMenu.setText("Net Device");

		javax.swing.JMenuItem mi = new javax.swing.JMenuItem("Net Base Address");
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				boolean done = false;
				if(mainWindow.netDevice != null){
					while(!done){
						java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, "New base address for Net Device", "Net Device Base Address", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("0x%04X", mainWindow.netDevice.getBaseAddress()));
						if(s == null){
							done = true;
						}else{
							try{
								java.lang.Integer newAddress = java.lang.Integer.decode(s);
								mainWindow.netDevice.setBaseAddress(newAddress.intValue());
								done = true;
							}catch(java.lang.NumberFormatException ex){
								mainWindow.error("Please enter a positive integer value");
							}
						}
					}
				}
			}
		});
		netMenu.add(mi);

		this.netMenuItem = new javax.swing.JCheckBoxMenuItem("Activate Net Device");
		this.netMenuItem.setSelected(false);
		this.netMenuItem.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				if(mainWindow.netDevice != null){
					if(mainWindow.netMenuItem.getState()){
						mainWindow.netDevice.start();
					}else{
						mainWindow.netDevice.stop();
					}
				}
			}
		});
		netMenu.add(this.netMenuItem);

		mi = new javax.swing.JMenuItem("Net Device Configuration");
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				if(mainWindow.netDevice != null){
					boolean done = false;
					gui.NetConfPane netconf = new gui.NetConfPane(mainWindow.netDevice.getLocalPort(), mainWindow.netDevice.getRemotePort(), mainWindow.netDevice.getRemoteIp());
					Object[] options = {"OK", "Cancel"};
					while(!done){
						int n =	javax.swing.JOptionPane.showOptionDialog(mainWindow, netconf, "Net Device Configuration", javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
						if(n == 0){
							if(netconf.checkSanity()){
								mainWindow.netDevice.configure(netconf.getLPort(), netconf.getRIp(), netconf.getRPort());
								done = true;
							}else{
								mainWindow.error("Please, enter a positive value for Local and Remote Port fields");
							}
						}else{
							done = true;
						}
					}
				}
			}
		});
		netMenu.add(mi);

		return(netMenu);
	}
	private javax.swing.JMenu initViewMenu(){
		javax.swing.JMenu viewMenu = new javax.swing.JMenu();
		viewMenu.setText("View");
		padMenuItem = new javax.swing.JCheckBoxMenuItem("Pad");
		padMenuItem.setSelected(true);
		padMenuItem.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				mainWindow.togglePadView();
			}
		});
		viewMenu.add(padMenuItem);

		viewMenu.addSeparator();

		this.colourMemoryAccess.setSelected(true);
		this.colourMemoryAccess.setText("Memory Access");
		this.colourMemoryAccess.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				mainWindow.reloadMemoryValues();
			}
		});
		viewMenu.add(this.colourMemoryAccess);

		this.colourMemoryChanges.setSelected(true);
		this.colourMemoryChanges.setText("Memory Changes");
		this.colourMemoryChanges.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				mainWindow.reloadMemoryValues();
			}
		});
		viewMenu.add(this.colourMemoryChanges);

		this.colourRegisterAccess.setSelected(true);
		this.colourRegisterAccess.setText("Register Access");
		this.colourRegisterAccess.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				mainWindow.reloadRegisterValues();
			}
		});
		viewMenu.add(this.colourRegisterAccess);

		this.colourRegisterChanges.setSelected(true);
		this.colourRegisterChanges.setText("Register Changes");
		this.colourRegisterChanges.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				mainWindow.reloadRegisterValues();
			}
		});
		viewMenu.add(this.colourRegisterChanges);

		viewMenu.addSeparator();

		javax.swing.JCheckBoxMenuItem mi = new javax.swing.JCheckBoxMenuItem("Program Panel");
		mi.setSelected(true);
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				javax.swing.JCheckBoxMenuItem auxMi = (javax.swing.JCheckBoxMenuItem)e.getSource();
				mainWindow.programPanel.setVisible(auxMi.isSelected());
			}
		});
		viewMenu.add(mi);
		mi = new javax.swing.JCheckBoxMenuItem("Memory Panel");
		mi.setSelected(true);
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				javax.swing.JCheckBoxMenuItem auxMi = (javax.swing.JCheckBoxMenuItem)e.getSource();
				mainWindow.memoryPanel.setVisible(auxMi.isSelected());
			}
		});
		viewMenu.add(mi);
		mi = new javax.swing.JCheckBoxMenuItem("Register Panel");
		mi.setSelected(true);
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				javax.swing.JCheckBoxMenuItem auxMi = (javax.swing.JCheckBoxMenuItem)e.getSource();
				mainWindow.registerPanel.setVisible(auxMi.isSelected());
			}
		});
		viewMenu.add(mi);
		mi = new javax.swing.JCheckBoxMenuItem("Stack Panel");
		mi.setSelected(false);
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				javax.swing.JCheckBoxMenuItem auxMi = (javax.swing.JCheckBoxMenuItem)e.getSource();
				mainWindow.stackPanel.setVisible(auxMi.isSelected());
			}
		});
		viewMenu.add(mi);

		return(viewMenu);
	}

	//Bottom Panel
	private javax.swing.JPanel getBotomPanel(){
		javax.swing.JPanel p = new javax.swing.JPanel(new java.awt.GridBagLayout());
		p.setBorder( new javax.swing.border.TitledBorder(""));
		java.awt.GridBagConstraints c;
		c = new java.awt.GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(0,0,0,0), 0, 0);
		p.add(getPCPanel(), c);
		c = new java.awt.GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(0,0,0,0), 0, 0);
		p.add(getFlagsPanel(), c);
		c = new java.awt.GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(0,0,0,0), 0, 0);
		p.add(getInterruptPanel(), c);
		c = new java.awt.GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(0,0,0,0), 0, 0);
		p.add(getInterruptCallsPanel(), c);
		return(p);
	}

	private javax.swing.JPanel getPCPanel(){
		javax.swing.JPanel auxp = new javax.swing.JPanel();
		auxp.setBorder(new javax.swing.border.TitledBorder("PC"));
		this.PCField = new javax.swing.JTextField("0x000", 7);
		this.PCField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.PCField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.PCField.setEditable(false);
		auxp.add(this.PCField);
		return(auxp);
	}
	private javax.swing.JPanel getInterruptCallsPanel(){
		javax.swing.JPanel auxp = new javax.swing.JPanel();
		auxp.setBorder(new javax.swing.border.TitledBorder("Interrupt Calls"));
		javax.swing.JLabel auxl = new javax.swing.JLabel("H:");
		auxp.add(auxl);
		this.TField = new javax.swing.JTextField("0", 2);
		this.TField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.TField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.TField.setEditable(false);
		auxp.add(this.TField);
		auxl = new javax.swing.JLabel("M:");
		auxp.add(auxl);
		this.HField = new javax.swing.JTextField("0", 2);
		this.HField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.HField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.HField.setEditable(false);
		auxp.add(this.HField);
		auxl = new javax.swing.JLabel("L:");
		auxp.add(auxl);
		this.LField = new javax.swing.JTextField("0", 2);
		this.LField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.LField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.LField.setEditable(false);
		auxp.add(this.LField);
		return(auxp);
	}
	private javax.swing.JPanel getInterruptPanel(){
		javax.swing.JPanel auxp = new javax.swing.JPanel();
		auxp.setBorder( new javax.swing.border.TitledBorder("Interrupt Flags"));
		javax.swing.JLabel auxl = new javax.swing.JLabel("EI:");
		auxp.add(auxl);
		this.EIField = new javax.swing.JTextField("0", 2);
		this.EIField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.EIField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.EIField.setEditable(false);
		auxp.add(this.EIField);
		auxl = new javax.swing.JLabel("T:");
		auxp.add(auxl);
		this.TMField = new javax.swing.JTextField("0", 2);
		this.TMField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.TMField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.TMField.setEditable(false);
		auxp.add(this.TMField);
		auxl = new javax.swing.JLabel("M:");
		auxp.add(auxl);
		this.HMField = new javax.swing.JTextField("0", 2);
		this.HMField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.HMField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.HMField.setEditable(false);
		auxp.add(this.HMField);
		auxl = new javax.swing.JLabel("L:");
		auxp.add(auxl);
		this.LMField = new javax.swing.JTextField("0", 2);
		this.LMField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.LMField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.LMField.setEditable(false);
		auxp.add(this.LMField);
		return(auxp);

	}
	//Flags
	private javax.swing.JPanel getFlagsPanel(){
		javax.swing.JPanel auxp = new javax.swing.JPanel();
		auxp.setBorder( new javax.swing.border.TitledBorder("Processor Flags"));
		javax.swing.JLabel auxl = new javax.swing.JLabel("N:");
		auxp.add(auxl);
		this.NField = new javax.swing.JTextField("0",2);
		this.NField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.NField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.NField.setEditable(false);
		auxp.add(this.NField);
		auxl = new javax.swing.JLabel("Z:");
		auxp.add(auxl);
		this.ZField = new javax.swing.JTextField("0",2);
		this.ZField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.ZField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.ZField.setEditable(false);
		auxp.add(this.ZField);
		auxl = new javax.swing.JLabel("C:");
		auxp.add(auxl);
		this.CField = new javax.swing.JTextField("0",2);
		this.CField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.CField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.CField.setEditable(false);
		auxp.add(this.CField);
		auxl = new javax.swing.JLabel("V:");
		auxp.add(auxl);
		this.VField = new javax.swing.JTextField("0",2);
		this.VField.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 15));
		this.VField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.VField.setEditable(false);
		auxp.add(this.VField);
		return(auxp);
	}

	//Stack Panel
	private javax.swing.JPanel stackPanel = null;
	private javax.swing.JList stackList = null;
	
	private void reloadStackValues(){
		this.stackList.setListData(this.processor.mem.getMemoryVector((0x0000FFFF & this.processor.rb.getSilentSP())+1, this.processor.getBaseSP() - (0x0000FFFF & this.processor.rb.getSilentSP())));
	}
	private javax.swing.JComponent getStackList(){
		this.stackList = new javax.swing.JList();
		this.stackList.setBorder(new javax.swing.border.LineBorder(java.awt.Color.gray));
		this.stackList.setBackground(java.awt.Color.WHITE);
		this.stackList.setPreferredSize(new java.awt.Dimension(100, 370));
		this.stackList.setMinimumSize(new java.awt.Dimension(100, 370));
		this.stackList.setCellRenderer(new gui.MainWindow.StackRender());
		return(this.stackList);
	}
	private javax.swing.JPanel getStackPanel(){
		this.stackPanel = new javax.swing.JPanel(new java.awt.BorderLayout());
		this.stackPanel.setBorder( new javax.swing.border.TitledBorder("Stack"));
		javax.swing.JTextField aux = new javax.swing.JTextField("");
		aux.setEditable(false);
		aux.setBorder(null);
		this.stackPanel.add(aux, java.awt.BorderLayout.NORTH);
		this.stackPanel.add(this.getStackList(), java.awt.BorderLayout.CENTER);
		this.stackPanel.setVisible(false);
		return(this.stackPanel);
	}

	class StackRender extends javax.swing.JPanel implements javax.swing.ListCellRenderer{
		static final long serialVersionUID = 0;
		javax.swing.JTextField t = new javax.swing.JTextField(10);
//		javax.swing.JTextField pos = new javax.swing.JTextField(6);

		java.lang.Short memValue = null;
		java.lang.Short posValue = null;
		public java.awt.Component getListCellRendererComponent(javax.swing.JList list, java.lang.Object value, int index, boolean selected, boolean focused) {
			//Extremely dirty trick for java: two shorts are encoded into a Integer
			java.lang.Integer aux = (java.lang.Integer) value;
			memValue = (short)(aux.intValue() & 0x0000FFFF);
			posValue = (short)((aux.intValue() & 0xFFFF0000)>>16);
			t.setBackground(java.awt.Color.WHITE);				

			//this.setLayout(new java.awt.GridLayout(0,2));
			this.setLayout(new java.awt.BorderLayout());
			t.setText(String.format("0x%04X", memValue.shortValue()));
			t.setFont(mainWindow.registerFont);
			t.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
			t.setBorder(null);
			this.add(t, java.awt.BorderLayout.CENTER);
			return(this);
		}
	}

	//Memory Panel
	private javax.swing.JTextField memoryField = null;
	private javax.swing.JPanel memoryPanel = null;
	private javax.swing.JList memoryList = null;

	private int lastOffset = 0x0000;
	private int nValues = 60;
	public void reloadMemoryValues(){
		this.memoryList.setListData(this.processor.mem.getMemoryVector(lastOffset, nValues));
		this.memoryField.setText(java.lang.String.format("0x%04X", this.lastOffset));
	}
	private void changeListValues(){
		int newOffset = 0;
		try{
			newOffset = java.lang.Integer.decode(this.memoryField.getText()).intValue();
			this.lastOffset = newOffset;
			this.reloadMemoryValues();
		}catch(java.lang.NumberFormatException e){
		}
	}
	private javax.swing.JComponent getMemoryField(){
		this.memoryField = new javax.swing.JTextField("0x0000");
		this.memoryField.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				changeListValues();
			}
		});
		return(this.memoryField);
	}

	private javax.swing.JComponent getMemoryList(){
		this.memoryList = new javax.swing.JList();
		this.memoryList.setCellRenderer(new gui.MainWindow.MemoryRender());

		java.awt.event.MouseListener mouseListener = new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent event) {
				if (event.getClickCount() == 1) {
					int index = memoryList.locationToIndex(event.getPoint());
					if(index >= 0){
						java.lang.Integer aux = (java.lang.Integer) memoryList.getModel().getElementAt(index);
						if(aux != null){
							short memValue = (short)(aux.intValue() & 0x0000FFFF);
							short posValue = (short)((aux.intValue() & 0xFFFF0000)>>16);
							boolean done = false;
							while(!done){
								java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, java.lang.String.format("New value for 0x%04X: ", posValue), "Memory Content", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("0x%04X", memValue));
								if(s==null){
									done = true;
								}else{
									try{
										java.lang.Short newValue = (short)(java.lang.Integer.decode(s) & 0x0000FFFF);
										mainWindow.processor.mem.setWord(posValue, newValue);
										mainWindow.memoryChanged();
										done = true;
									}catch(java.lang.NumberFormatException ex){
										mainWindow.error("Please enter a positive short value");
									}
								}
							}
						}
					}
				}
			}
		};
		this.memoryList.addMouseListener(mouseListener);

		return(this.memoryList);
	}
	private javax.swing.JPanel getMemoryPanel(){
		this.memoryPanel = new javax.swing.JPanel(new java.awt.BorderLayout());
		this.memoryPanel.setBorder( new javax.swing.border.TitledBorder("Memory"));
		this.memoryPanel.add(this.getMemoryField(), java.awt.BorderLayout.NORTH);
		javax.swing.JScrollPane jsp = new javax.swing.JScrollPane();
		jsp.getViewport().setView(this.getMemoryList());
		this.memoryPanel.add(jsp,java.awt.BorderLayout.CENTER);
		return(this.memoryPanel);
	}

	class MemoryRender extends javax.swing.JPanel implements javax.swing.ListCellRenderer{
		static final long serialVersionUID = 0;
		javax.swing.JTextField t = new javax.swing.JTextField(10);
		javax.swing.JTextField pos = new javax.swing.JTextField(6);

		java.lang.Short memValue = null;
		java.lang.Integer posValue = null;
		public java.awt.Component getListCellRendererComponent(javax.swing.JList list, java.lang.Object value, int index, boolean selected, boolean focused) {
			//Extremely dirty trick for java: two shorts are encoded into a Integer
			java.lang.Integer aux = (java.lang.Integer) value;
			memValue = (short)(aux.intValue() & 0x0000FFFF);
			posValue = ((aux.intValue()>>16) & 0x0000FFFF);
			t.setBackground(java.awt.Color.WHITE);				
			if(mainWindow.memoryAccess.contains(new java.lang.Integer(posValue))){
				if(mainWindow.colourMemoryAccess.isSelected()){
					t.setBackground(java.awt.Color.YELLOW);
				}
			}
			if(mainWindow.memoryChanges.contains(new java.lang.Integer(posValue))){
				if(mainWindow.colourMemoryChanges.isSelected()){
					t.setBackground(java.awt.Color.RED);
				}
			}

			//this.setLayout(new java.awt.GridLayout(0,2));
			this.setLayout(new java.awt.BorderLayout());
			t.setText(String.format("0x%04X", memValue.shortValue()));
			t.setFont(mainWindow.valuesFont);
			t.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
			t.setBorder(null);
			pos.setBorder(null);
			pos.setFont(mainWindow.valuesFont);
			pos.setText(String.format("0x%04X", posValue.shortValue()));
			pos.setBackground(java.awt.Color.lightGray);
			pos.setHorizontalAlignment(javax.swing.JTextField.CENTER);
			this.add(pos, java.awt.BorderLayout.WEST);
			this.add(t, java.awt.BorderLayout.CENTER);
			return(this);
		}
	}
	//RegisterPanel
	private javax.swing.JList registerList = null;
	private javax.swing.JPanel registerPanel = null;

	public void reloadRegisterValues(){
		this.registerList.setListData(this.processor.rb.getRegisterVector());
	}

	private javax.swing.JComponent getRegisterList(){
		this.registerList = new javax.swing.JList();
		this.registerList.setBorder(new javax.swing.border.LineBorder(java.awt.Color.gray));
		this.registerList.setBackground(this.getBackground());
		this.registerList.setVisibleRowCount(16);
		this.registerList.setCellRenderer(new gui.MainWindow.RegisterRender());

		java.awt.event.MouseListener mouseListener = new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent event) {
				if (event.getClickCount() == 1) {
					int index = registerList.locationToIndex(event.getPoint());
					if(index >= 0){
						java.lang.Integer aux = (java.lang.Integer) registerList.getModel().getElementAt(index);
						if(aux != null){
							short regValue = (short)(aux.intValue() & 0x0000FFFF);
							short posValue = (short)((aux.intValue() & 0xFFFF0000)>>16);
							boolean done = false;
							while(!done){
								java.lang.String s = (java.lang.String)javax.swing.JOptionPane.showInputDialog(mainWindow, java.lang.String.format("New value for Reg %d: ", posValue), "Register Content", javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, java.lang.String.format("0x%04X", regValue));
								if(s==null){
									done = true;
								}else{
									try{
										java.lang.Short newValue = (short)(java.lang.Integer.decode(s) & 0x0000FFFF);
										mainWindow.processor.rb.setRegister(posValue, newValue);
										mainWindow.registerChanged();
										done = true;
									}catch(java.lang.NumberFormatException ex){
										mainWindow.error("Please enter a positive short value");
									}
								}
							}
						}
					}
				}
			}
		};
		this.registerList.addMouseListener(mouseListener);
		return(this.registerList);
	}
	private javax.swing.JPanel getRegisterPanel(){
		this.registerPanel = new javax.swing.JPanel(new java.awt.BorderLayout());
		this.registerPanel.setBorder( new javax.swing.border.TitledBorder("Registers"));
		javax.swing.JTextField aux = new javax.swing.JTextField("");
		aux.setEditable(false);
		aux.setBorder(null);
		this.registerPanel.add(aux, java.awt.BorderLayout.NORTH);
		this.registerPanel.add(this.getRegisterList(), java.awt.BorderLayout.CENTER);
		return(this.registerPanel);
	}

	class RegisterRender extends javax.swing.JPanel implements javax.swing.ListCellRenderer{
		static final long serialVersionUID = 0;
		javax.swing.JTextField t = new javax.swing.JTextField(10);
		javax.swing.JTextField pos = new javax.swing.JTextField(6);

		java.lang.Short regValue = null;
		java.lang.Short posValue = null;
		public java.awt.Component getListCellRendererComponent(javax.swing.JList list, java.lang.Object value, int index, boolean selected, boolean focused) {
			//Extremely dirty trick for java: two shorts are encoded into a Integer
			java.lang.Integer aux = (java.lang.Integer) value;
			regValue = (short)(aux.intValue() & 0x0000FFFF);
			posValue = (short)((aux.intValue() & 0xFFFF0000)>>16);
			t.setBackground(java.awt.Color.WHITE);				
			if(mainWindow.registerAccess.contains(new java.lang.Integer(posValue))){
				if(mainWindow.colourRegisterAccess.isSelected()){
					t.setBackground(java.awt.Color.YELLOW);
				}
			}
			if(mainWindow.registerChanges.contains(new java.lang.Integer(posValue))){
				if(mainWindow.colourRegisterChanges.isSelected()){
					t.setBackground(java.awt.Color.RED);
				}
			}

			//this.setLayout(new java.awt.GridLayout(0,2));
			this.setBorder(new javax.swing.border.LineBorder(java.awt.Color.LIGHT_GRAY, 1, false));
			this.setLayout(new java.awt.BorderLayout());
			t.setText(String.format("0x%04X", regValue.shortValue()));
			t.setFont(mainWindow.registerFont);
			t.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
			t.setBorder(null);
			pos.setBorder(null);
			pos.setFont(mainWindow.registerFont);
			pos.setText(String.format("%d", posValue.shortValue()));
			pos.setBackground(java.awt.Color.lightGray);
			pos.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
			this.add(pos, java.awt.BorderLayout.WEST);
			this.add(t, java.awt.BorderLayout.CENTER);
			return(this);
		}
	}


	//ProgramPanel
	private javax.swing.JList programList = null;
	private javax.swing.JPanel programPanel = null;
	private javax.swing.JTextField programField = null;
	private int lastProgram = 0;

	private void setProgramListData(java.util.Vector<java.lang.Integer> v){
		java.util.Iterator<java.lang.Integer> i = v.iterator();
		java.util.Vector<java.lang.String> res = new java.util.Vector<java.lang.String>();
		core.InstructionClass auxInstruction = null;
		short memValue;
		short posValue;
		java.lang.Integer aux;
		while(i.hasNext()){
			aux = i.next();
			memValue = (short)(aux.intValue() & 0x0000FFFF);
			posValue = (short)((aux.intValue() & 0xFFFF0000)>>16);
			auxInstruction = new core.InstructionClass(memValue);
			if(auxInstruction.inst.getFormat() == 4){
				if(i.hasNext()){
					aux = i.next();
					memValue = (short)(aux.intValue() & 0x0000FFFF);
					auxInstruction.setByteCode2(memValue);
					res.add(java.lang.String.format("0x%04X %s", posValue, auxInstruction.getAssembly()));
					res.add(java.lang.String.format("0x%04X ", posValue+1));
				}
			}else{
				res.add(java.lang.String.format("0x%04X %s", posValue, auxInstruction.getAssembly()));
			}
		}
		this.programList.setListData(res);
	}
	public void reloadProgramValues(int mempos, int n){
		int aux = 0;
		if(mempos>0xD){
			aux = mempos-0xD;
		}
		this.setProgramListData(this.processor.mem.getMemoryVector(aux, n));
	}
	public void reloadProgramValues(){
		this.reloadProgramValues(0x0000, 60);
	}
	public void reloadProgramValues(int PC){
		this.reloadProgramValues((0x0000FFFF & PC), 60);
	}
	private void changeProgramListValues(){
		try{
			this.lastProgram = java.lang.Integer.decode(this.programField.getText()).intValue();
			this.followPCMenuItem.setSelected(false);
			this.reloadProgramValues(this.lastProgram, 60);
		}catch(java.lang.NumberFormatException e){
		}
	}
	private javax.swing.JComponent getProgramDirectionPanel(){
		//javax.swing.JPanel auxPDP = new javax.swing.JPanel();
		this.programField = new javax.swing.JTextField("0x0000", 5);
		this.programField.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				changeProgramListValues();
			}
		});
/*		auxPDP.add(this.programField);
		
		javax.swing.JButton auxJB = new javax.swing.JButton("PC");
		auxJB.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent e){
				reloadProgramValues(processor.cu.getPC());
			}
		});
		auxPDP.add(auxJB);
//		return(auxPDP);*/
		return(this.programField);
	}
	private javax.swing.JComponent getProgramList(){
		this.programList = new javax.swing.JList();
		this.programList.setCellRenderer(new gui.MainWindow.ProgramRender());
		java.awt.event.MouseListener mouseListener = new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent event) {
				if (event.getClickCount() == 1) {
					int index = programList.locationToIndex(event.getPoint());
					if(index >= 0){
						java.lang.String aux = (java.lang.String) programList.getModel().getElementAt(index);
						//System.out.println("Inst: " + line + " n:" + line.length());
						if(aux != null){
							java.lang.String line = aux.substring(7);
							if(line.length() > 0){
								try{
									short auxPos = java.lang.Integer.decode(aux.substring(0,6)).shortValue();
									core.InstructionClass auxInstruction = new core.InstructionClass(mainWindow.processor.mem.getWord(auxPos));
									if(auxInstruction.inst.getFormat() == 4){
										auxInstruction.setByteCode2(mainWindow.processor.mem.getWord(auxPos+1));
									}
									gui.EditorPane editor = new gui.EditorPane(auxInstruction);
									Object[] options = {"OK", "Cancel"};
									int n =	javax.swing.JOptionPane.showOptionDialog(mainWindow, editor, "Line editor", javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
									if(n == 0){
										java.lang.String auxInstrStr = editor.getStringInstr();
										if(auxInstrStr != null){
											auxInstruction = new core.InstructionClass(editor.getStringInstr());
											mainWindow.processor.setInstruction(auxPos, auxInstruction);
											mainWindow.programModified = true;
										}
									}
								}catch(java.lang.NumberFormatException e){
								}
							}else{
								error("You cannot edit this memory position.");
							}
						}
					}
				}
			}
		};
		this.programList.addMouseListener(mouseListener);

		return(this.programList);
	}
	private javax.swing.JPanel getProgramPanel(){
		this.programPanel = new javax.swing.JPanel(new java.awt.BorderLayout());
		this.programPanel.setMinimumSize(new java.awt.Dimension(190,20));
		this.programPanel.setPreferredSize(new java.awt.Dimension(190,20));
		//this.programPanel.setMaximumSize(new java.awt.Dimension(140,20));
		this.programPanel.setBorder( new javax.swing.border.TitledBorder("Program"));
		javax.swing.JScrollPane jsp = new javax.swing.JScrollPane();
		jsp.getViewport().setView(this.getProgramList());
		this.programPanel.add(jsp, java.awt.BorderLayout.CENTER);
//		this.programPanel.add(this.getProgramList(), java.awt.BorderLayout.CENTER);
		this.programPanel.add(this.getProgramDirectionPanel(), java.awt.BorderLayout.NORTH);
		return(this.programPanel);
	}

	class ProgramRender extends javax.swing.JPanel implements javax.swing.ListCellRenderer{
		static final long serialVersionUID = 0;
		javax.swing.JTextField t = new javax.swing.JTextField();
		javax.swing.JTextField pos = new javax.swing.JTextField(6);

		public java.awt.Component getListCellRendererComponent(javax.swing.JList list, java.lang.Object value, int index, boolean selected, boolean focused) {
			//Extremely dirty trick for java: two shorts are encoded into a Integer
			java.lang.String aux = (java.lang.String) value;
			short auxPos = 0;
			short auxPC = processor.cu.getPC();
			short auxPrevPC = processor.cu.getPrevPC();

			//this.setLayout(new java.awt.GridLayout(0,2));
			try{
				auxPos = java.lang.Integer.decode(aux.substring(0,6)).shortValue();
			}catch(java.lang.NumberFormatException e){
			}
			this.setLayout(new java.awt.BorderLayout());
			t.setText(aux.substring(7));
			t.setFont(mainWindow.valuesFont);
			t.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
			t.setBorder(null);
			if(auxPos == auxPC){
				t.setBackground(java.awt.Color.cyan);
			}else if(auxPos == auxPrevPC){
				t.setBackground(java.awt.Color.yellow);
			}else{
				t.setBackground(java.awt.Color.white);				
			}
			pos.setBorder(null);
			pos.setFont(mainWindow.valuesFont);
			pos.setText(aux.substring(0, 6));
			pos.setBackground(java.awt.Color.lightGray);
			pos.setHorizontalAlignment(javax.swing.JTextField.CENTER);
			this.add(pos, java.awt.BorderLayout.WEST);
			this.add(t, java.awt.BorderLayout.CENTER);
			return(this);
		}
	}

	/**
	 * Interface for call back functions
	 */
	java.util.Set<java.lang.Integer> registerChanges = new java.util.HashSet<java.lang.Integer>(); 
	java.util.Set<java.lang.Integer> memoryChanges = new java.util.HashSet<java.lang.Integer>();
	java.util.Set<java.lang.Integer> registerAccess = new java.util.HashSet<java.lang.Integer>(); 
	java.util.Set<java.lang.Integer> memoryAccess = new java.util.HashSet<java.lang.Integer>();
	public void registerChanged() {
		if(!this.silentRun){
			this.reloadRegisterValues();
		}
	}
	public void registerChanged(int n){
		this.registerChanges.add(n);
		if(n == 15){
			if(!this.silentRun){
				this.reloadStackValues();
			}
		}
	}
	public void registerAccessed(int n){
		this.registerAccess.add(n);
	}

	public void memoryChanged() {
		if(!this.silentRun){
			this.reloadMemoryValues();
			this.reloadStackValues();
			this.reloadProgramValues(this.lastProgram);
		}
		if(this.pad != null){
			this.pad.reloadMemDisplayValue();
		}
	}
	public void memoryChanged(int address){
		this.memoryChanges.add(address);
	}
	public void memoryAccessed(int address){
		this.memoryAccess.add(address);
	}

	public void PCChanged() {
		if(!this.silentRun){
			short pc = this.processor.cu.getPC();
			if(this.followPCMenuItem.isSelected()){
				this.reloadProgramValues(pc);
				this.lastProgram = pc;
			}else{
				this.reloadProgramValues(this.lastProgram);
			}
			if(this.PCField != null){
				this.PCField.setText(java.lang.String.format("0x%04X", pc));
			}
		}
	}

	public void PSRChanged() {
		if(!this.silentRun){
			if(this.NField != null){
				if(this.processor.psr.getNChanged()){
					this.NField.setBackground(java.awt.Color.YELLOW);
				}else{
					this.NField.setBackground(this.getBackground());
				}
				this.NField.setText(""+this.processor.psr.getN());
			}
			if(this.ZField != null){
				if(this.processor.psr.getZChanged()){
					this.ZField.setBackground(java.awt.Color.YELLOW);
				}else{
					this.ZField.setBackground(this.getBackground());
				}
				this.ZField.setText(""+this.processor.psr.getZ());
			}
			if(this.CField != null){
				if(this.processor.psr.getCChanged()){
					this.CField.setBackground(java.awt.Color.YELLOW);
				}else{
					this.CField.setBackground(this.getBackground());
				}
				this.CField.setText(""+this.processor.psr.getC());
			}
			if(this.VField != null){
				if(this.processor.psr.getVChanged()){
					this.VField.setBackground(java.awt.Color.YELLOW);
				}else{
					this.VField.setBackground(this.getBackground());
				}
				this.VField.setText(""+this.processor.psr.getV());
			}
		}
		if(this.EIField != null){
			if(this.processor.psr.getEIChanged()){
				this.EIField.setBackground(java.awt.Color.YELLOW);
			}else{
				this.EIField.setBackground(this.getBackground());
			}
			this.EIField.setText(""+this.processor.psr.getEI());
		}
		if(this.TMField != null){
			if(this.processor.psr.getTIMChanged()){
				this.TMField.setBackground(java.awt.Color.YELLOW);
			}else{
				this.TMField.setBackground(this.getBackground());
			}
			this.TMField.setText(""+this.processor.psr.getTIM());
		}
		if(this.HMField != null){
			if(this.processor.psr.getHIMChanged()){
				this.HMField.setBackground(java.awt.Color.YELLOW);
			}else{
				this.HMField.setBackground(this.getBackground());
			}
			this.HMField.setText(""+this.processor.psr.getHIM());
		}
		if(this.LMField != null){
			if(this.processor.psr.getLIMChanged()){
				this.LMField.setBackground(java.awt.Color.YELLOW);
			}else{
				this.LMField.setBackground(this.getBackground());
			}
			this.LMField.setText(""+this.processor.psr.getLIM());
		}
	}
	public void allChanged(){
		this.registerChanged();
		this.memoryChanged();
		this.PCChanged();
		this.PSRChanged();
	}
	public void error(java.lang.String s){
		javax.swing.JOptionPane.showMessageDialog(this, s, "Error", javax.swing.JOptionPane.ERROR_MESSAGE);
	}
	public void procStopped(){
		this.silentRun = false;
		this.allChanged();
	}

	/**
	 * Pad management functions
	 */
	//Pad closed by closing its window
	public void padClosed(){
		this.padVisible = false;
		this.padMenuItem.setSelected(this.padVisible);
	}
	public void togglePadView(){
		padVisible = !padVisible;
		if(this.pad != null){
			this.pad.setVisible(this.padVisible);
		}else{
			mainWindow.error("External Pad not found");
		}
		this.padMenuItem.setSelected(this.padVisible);
	}
	public void padMoved(){
		//System.out.println("Pad disaccopled");
	}

	/**
	 * Core Interrupt Interface methods:
	 */
	public void raiseInterruptLine(int line){
		util.Messages.info(java.lang.String.format("GUI: Interrupt Line %d called\n", line));
		switch(line){
			case 1:
				if(this.TField != null){
					this.TField.setBackground(java.awt.Color.RED);
					this.TField.setText("1");
				}
				break;
			case 2:
				if(this.HField != null){
					this.HField.setBackground(java.awt.Color.RED);
					this.HField.setText("1");
				}
				break;
			case 3:
				if(this.LField != null){
					this.LField.setBackground(java.awt.Color.RED);
					this.LField.setText("1");
				}
				break;
		}
	}
	public void lowerInterruptLine(int line){
		util.Messages.info(java.lang.String.format("GUI: Interrupt Line %d lowered\n", line));
		switch(line){
			case 1:
				if(this.TField != null){
					this.TField.setBackground(this.getBackground());
					this.TField.setText("0");
				}
				break;
			case 2:
				if(this.HField != null){
					this.HField.setBackground(this.getBackground());
					this.HField.setText("0");
				}
				break;
			case 3:
				if(this.LField != null){
					this.LField.setBackground(this.getBackground());
					this.LField.setText("0");
				}
				break;
		}
	}
}
